// TBN calculation

#define EPSILON		0.000001


void CalcTBN(/*vert0*/  in vec3 vPosition0, in vec2 vTexcoord0,
			 /*vert1*/  in vec3 vPosition1, in vec2 vTexcoord1,
			 /*vert2*/  in vec3 vPosition2, in vec2 vTexcoord2,
			 /*output*/ out mat3 mTBN)
{
	vec3	e0 = vec3(	vPosition1.x - vPosition0.x,
						vTexcoord1.x - vTexcoord0.x,
						vTexcoord1.y - vTexcoord0.y );
	vec3	e1 = vec3(	vPosition2.x - vPosition0.x,
						vTexcoord2.x - vTexcoord0.x,
						vTexcoord2.y - vTexcoord0.y );
	vec3	cp = cross( e0, e1 );
	
	vec3	normal = normalize( cross( vPosition1 - vPosition0, vPosition2 - vPosition0 ) );
	vec3	tangent;
	vec3	binormal;
	
	if ( abs(cp.x) > EPSILON ) {
		tangent.x  = -cp.y/cp.x;
		binormal.x = -cp.z/cp.x;
	}
	else {
		tangent.x  = 0.0;
		binormal.x = 0.0;
	}
	
	e0.x = vPosition1.y - vPosition0.y;
	e1.x = vPosition2.y - vPosition0.y;
	cp = cross( e0, e1 );
	
	if ( abs(cp.x) > EPSILON ) {
		tangent.y  = -cp.y/cp.x;
		binormal.y = -cp.z/cp.x;
	}
	else {
		tangent.y  = 0.0;
		binormal.y = 0.0;
	}
	
	e0.x = vPosition1.z - vPosition0.z;
	e1.x = vPosition2.z - vPosition0.z;
	cp = cross( e0, e1 );
	
	if ( abs(cp.x) > EPSILON ) {
		tangent.z  = -cp.y/cp.x;
		binormal.z = -cp.z/cp.x;
	}
	else {
		tangent.z  = 0.0;
		binormal.z = 0.0;
	}
	
	if ( dot( cross( tangent, binormal ), normal ) < 0.0 )
		tangent = -tangent;
	
	mTBN = mat3( tangent.x, binormal.x, normal.x,
				 tangent.y, binormal.y, normal.y,
				 tangent.z, binormal.z, normal.z );
}


void CalcTBN(/*vert0*/  in vec3 vPosition0, in vec2 vTexcoord0,
			 /*vert1*/  in vec3 vPosition1, in vec2 vTexcoord1,
			 /*vert2*/  in vec3 vPosition2, in vec2 vTexcoord2,
			 /*bump*/   in float fBumpFactor /*= 0.1*/,
			 /*output*/ out mat3 mTBN)
{
	vec3	sw;
	vec3	u  = vec3( vTexcoord0.x, vTexcoord1.x, vTexcoord2.x );
	vec3	v  = vec3( vTexcoord0.y, vTexcoord1.y, vTexcoord2.y );
	vec3	id = vec3( 1.0, 1.0, 1.0 );
	
	sw = cross( u, id );
	sw = sw * ( fBumpFactor / dot(v, sw) );
	
	vec3	tangent  = vPosition0 * sw.x + vPosition1 * sw.y + vPosition2 * sw.z;
	
	sw = cross( v, id );
	sw = sw * ( fBumpFactor / dot(u, sw) );
	
	vec3	binormal = vPosition0 * sw.x + vPosition1 * sw.y + vPosition2 * sw.z;
	vec3	normal	 = normalize( cross( tangent, binormal ) );
	
	mTBN = mat3( tangent.x, binormal.x, normal.x,
				 tangent.y, binormal.y, normal.y,
				 tangent.z, binormal.z, normal.z );
}
